home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JTextPane.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  15.2 KB  |  455 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JTextPane.java    1.64 98/08/28
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package javax.swing;
  15.  
  16. import java.awt.*;
  17. import java.awt.event.ActionEvent;
  18.  
  19. import java.io.ObjectOutputStream;
  20. import java.io.ObjectInputStream;
  21. import java.io.IOException;
  22.  
  23. import javax.swing.text.*;
  24. import javax.swing.event.*;
  25. import javax.swing.plaf.*;
  26.  
  27. /**
  28.  * A text component that can be marked up with attributes that are
  29.  * represented graphically.  This component models paragraphs
  30.  * that are composed of runs of character level attributes.  Each
  31.  * paragraph may have a logical style attached to it which contains
  32.  * the default attributes to use if no overriden by attributes set
  33.  * on the paragraph or character run.  Components and images may
  34.  * be embedded in the flow of text.
  35.  * <p>
  36.  * For the keyboard keys used by this component in the standard Look and
  37.  * Feel (L&F) renditions, see the
  38.  * <a href="doc-files/Key-Index.html#JTextPane">JTextPane</a> key assignments.
  39.  * <p>
  40.  * <strong>Warning:</strong>
  41.  * Serialized objects of this class will not be compatible with
  42.  * future Swing releases.  The current serialization support is appropriate
  43.  * for short term storage or RMI between applications running the same
  44.  * version of Swing.  A future release of Swing will provide support for
  45.  * long term persistence.
  46.  *
  47.  * @author  Timothy Prinzing
  48.  * @version 1.64 08/28/98
  49.  * @see text.StyledEditorKit
  50.  */
  51. public class JTextPane extends JEditorPane {
  52.  
  53.     /**
  54.      * Constructs a new JTextPane.  A new instance of StyledEditorKit is
  55.      * created and set, and the document model set to null.
  56.      */
  57.     public JTextPane() {
  58.         super();
  59.         setEditorKit(new StyledEditorKit());
  60.     }
  61.  
  62.     /**
  63.      * Constructs a new JTextPane, with a specified document model.
  64.      * A new instance of text.StyledEditorKit is created and set.
  65.      *
  66.      * @param doc the document model
  67.      */
  68.     public JTextPane(StyledDocument doc) {
  69.         this();
  70.         setStyledDocument(doc);
  71.     }
  72.  
  73.     /**
  74.      * Returns the class ID for the UI.
  75.      *
  76.      * @return the ID ("TextPaneUI")
  77.      * @see JComponent#getUIClassID
  78.      * @see UIDefaults#getUI
  79.      */
  80.     public String getUIClassID() {
  81.         return uiClassID;
  82.     }
  83.  
  84.     /**
  85.      * Associates the editor with a text document.  This
  86.      * must be a StyledDocument.
  87.      *
  88.      * @param doc  the document to display/edit
  89.      * @exception IllegalArgumentException  if doc can't
  90.      *   be narrowed to a StyledDocument which is the
  91.      *   required type of model for this text component
  92.      */
  93.     public void setDocument(Document doc) {
  94.         if (doc instanceof StyledDocument) {
  95.             super.setDocument(doc);
  96.         } else {
  97.             throw new IllegalArgumentException("Model must be StyledDocument");
  98.         }
  99.     }
  100.  
  101.     /**
  102.      * Associates the editor with a text document.
  103.      * The currently registered factory is used to build a view for
  104.      * the document, which gets displayed by the editor.
  105.      *
  106.      * @param doc  the document to display/edit
  107.      */
  108.     public void setStyledDocument(StyledDocument doc) {
  109.         super.setDocument(doc);
  110.     }
  111.  
  112.     /**
  113.      * Fetches the model associated with the editor.  
  114.      *
  115.      * @return the model
  116.      */
  117.     public StyledDocument getStyledDocument() {
  118.         return (StyledDocument) getDocument();
  119.     } 
  120.  
  121.     /**
  122.      * Replaces the currently selected content with new content
  123.      * represented by the given string.  If there is no selection
  124.      * this amounts to an insert of the given text.  If there
  125.      * is no replacement text this amounts to a removal of the
  126.      * current selection.  The replacement text will have the
  127.      * attributes currently defined for input.  If the document is not
  128.      * editable, beep and return.  Then if the document is null, do nothing.
  129.      * If the content to insert is null or empty, ignore it.
  130.      * <p>
  131.      * This method is thread safe, although most Swing methods
  132.      * are not. Please see 
  133.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  134.      * and Swing</A> for more information.     
  135.      *
  136.      * @param content  the content to replace the selection with
  137.      */
  138.     public void replaceSelection(String content) {
  139.         if (! isEditable()) {
  140.             getToolkit().beep();
  141.             return;
  142.         }
  143.         Document doc = getStyledDocument();
  144.         if (doc != null) {
  145.             try {
  146.                 Caret caret = getCaret();
  147.                 int p0 = Math.min(caret.getDot(), caret.getMark());
  148.                 int p1 = Math.max(caret.getDot(), caret.getMark());
  149.                 if (p0 != p1) {
  150.                     doc.remove(p0, p1 - p0);
  151.                 }
  152.                 if (content != null && content.length() > 0) {
  153.                     doc.insertString(p0, content, getInputAttributes());
  154.                 }
  155.             } catch (BadLocationException e) {
  156.                 getToolkit().beep();
  157.             }
  158.         }
  159.     }
  160.  
  161.     /**
  162.      * Inserts a component into the document as a replacement
  163.      * for the currently selected content.  If there is no
  164.      * selection the component is effectively inserted at the 
  165.      * current position of the caret.  This is represented in
  166.      * the associated document as an attribute of one character 
  167.      * of content.  
  168.      *
  169.      * @param c    the component to insert
  170.      */
  171.     public void insertComponent(Component c) {
  172.         MutableAttributeSet inputAttributes = getInputAttributes();
  173.         inputAttributes.removeAttributes(inputAttributes);
  174.         StyleConstants.setComponent(inputAttributes, c);
  175.         replaceSelection(" ");
  176.         inputAttributes.removeAttributes(inputAttributes);
  177.     }
  178.  
  179.     /**
  180.      * Inserts an icon into the document as a replacement
  181.      * for the currently selected content.  If there is no
  182.      * selection the icon is effectively inserted at the 
  183.      * current position of the caret.  This is represented in
  184.      * the associated document as an attribute of one character 
  185.      * of content.  
  186.      * <p>
  187.      * This method is thread safe, although most Swing methods
  188.      * are not. Please see 
  189.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  190.      * and Swing</A> for more information.     
  191.      *
  192.      * @param g    the icon to insert
  193.      * @see Icon
  194.      */
  195.     public void insertIcon(Icon g) {
  196.         MutableAttributeSet inputAttributes = getInputAttributes();
  197.         inputAttributes.removeAttributes(inputAttributes);
  198.         StyleConstants.setIcon(inputAttributes, g);
  199.         replaceSelection(" ");
  200.         inputAttributes.removeAttributes(inputAttributes);
  201.     }
  202.  
  203.     /**
  204.      * Adds a new style into the logical style hierarchy.  Style attributes
  205.      * resolve from bottom up so an attribute specified in a child
  206.      * will override an attribute specified in the parent.
  207.      *
  208.      * @param nm   the name of the style (must be unique within the
  209.      *   collection of named styles).  The name may be null if the style 
  210.      *   is unnamed, but the caller is responsible
  211.      *   for managing the reference returned as an unnamed style can't
  212.      *   be fetched by name.  An unnamed style may be useful for things
  213.      *   like character attribute overrides such as found in a style 
  214.      *   run.
  215.      * @param parent the parent style.  This may be null if unspecified
  216.      *   attributes need not be resolved in some other style.
  217.      * @return the new Style 
  218.      */
  219.     public Style addStyle(String nm, Style parent) {
  220.         StyledDocument doc = getStyledDocument();
  221.         return doc.addStyle(nm, parent);
  222.     }
  223.  
  224.     /**
  225.      * Removes a named non-null style previously added to the document.  
  226.      *
  227.      * @param nm  the name of the style to remove
  228.      */
  229.     public void removeStyle(String nm) {
  230.         StyledDocument doc = getStyledDocument();
  231.         doc.removeStyle(nm);
  232.     }
  233.  
  234.     /**
  235.      * Fetches a named non-null style previously added.
  236.      *
  237.      * @param nm  the name of the style
  238.      * @return the style
  239.      */
  240.     public Style getStyle(String nm) {
  241.         StyledDocument doc = getStyledDocument();
  242.         return doc.getStyle(nm);
  243.     }
  244.  
  245.     /**
  246.      * Sets the logical style to use for the paragraph at the
  247.      * current caret position.  If attributes aren't explicitly set 
  248.      * for character and paragraph attributes they will resolve 
  249.      * through the logical style assigned to the paragraph, which
  250.      * in term may resolve through some hierarchy completely 
  251.      * independant of the element hierarchy in the document.
  252.      * <p>
  253.      * This method is thread safe, although most Swing methods
  254.      * are not. Please see 
  255.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  256.      * and Swing</A> for more information.     
  257.      *
  258.      * @param s  the logical style to assign to the paragraph, or null for
  259.      *  no style
  260.      */
  261.     public void setLogicalStyle(Style s) {
  262.         StyledDocument doc = getStyledDocument();
  263.         doc.setLogicalStyle(getCaretPosition(), s);
  264.     }
  265.  
  266.     /** 
  267.      * Fetches the logical style assigned to the paragraph 
  268.      * represented by the current position of the caret, or null.
  269.      *
  270.      * @return the style
  271.      */
  272.     public Style getLogicalStyle() {
  273.         StyledDocument doc = getStyledDocument();
  274.         return doc.getLogicalStyle(getCaretPosition());
  275.     }
  276.  
  277.     /**
  278.      * Fetches the character attributes in effect at the 
  279.      * current location of the caret, or null.  
  280.      *
  281.      * @return the attributes, or null
  282.      */
  283.     public AttributeSet getCharacterAttributes() {
  284.         StyledDocument doc = getStyledDocument();
  285.         Element run = doc.getCharacterElement(getCaretPosition());
  286.         if (run != null) {
  287.             return run.getAttributes();
  288.         }
  289.         return null;
  290.     }
  291.  
  292.     /**
  293.      * Applies the given attributes to character 
  294.      * content.  If there is a selection, the attributes
  295.      * are applied to the selection range.  If there
  296.      * is no selection, the attributes are applied to
  297.      * the input attribute set which defines the attributes
  298.      * for any new text that gets inserted.
  299.      * <p>
  300.      * This method is thread safe, although most Swing methods
  301.      * are not. Please see 
  302.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  303.      * and Swing</A> for more information.     
  304.      *
  305.      * @param attr the attributes
  306.      * @param replace if true, then replace the existing attributes first
  307.      */
  308.     public void setCharacterAttributes(AttributeSet attr, boolean replace) {
  309.         int p0 = getSelectionStart();
  310.         int p1 = getSelectionEnd();
  311.         if (p0 != p1) {
  312.             StyledDocument doc = getStyledDocument();
  313.             doc.setCharacterAttributes(p0, p1 - p0, attr, replace);
  314.         } else {
  315.             MutableAttributeSet inputAttributes = getInputAttributes();
  316.             if (replace) {
  317.                 inputAttributes.removeAttributes(inputAttributes);
  318.             }
  319.             inputAttributes.addAttributes(attr);
  320.         }
  321.     }
  322.  
  323.     /**
  324.      * Fetches the current paragraph attributes in effect
  325.      * at the location of the caret, or null if none.
  326.      *
  327.      * @return the attributes
  328.      */
  329.     public AttributeSet getParagraphAttributes() {
  330.         StyledDocument doc = getStyledDocument();
  331.         Element paragraph = doc.getParagraphElement(getCaretPosition());
  332.         if (paragraph != null) {
  333.             return paragraph.getAttributes();
  334.         }
  335.         return null;
  336.     }
  337.  
  338.     /**
  339.      * Applies the given attributes to paragraphs.  If
  340.      * there is a selection, the attributes are applied
  341.      * to the paragraphs that intersect the selection.
  342.      * if there is no selection, the attributes are applied
  343.      * to the paragraph at the current caret position.
  344.      * <p>
  345.      * This method is thread safe, although most Swing methods
  346.      * are not. Please see 
  347.      * <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">Threads
  348.      * and Swing</A> for more information.     
  349.      *
  350.      * @param attr the non-null attributes
  351.      * @param replace if true, replace the existing attributes first
  352.      */
  353.     public void setParagraphAttributes(AttributeSet attr, boolean replace) {
  354.         int p0 = getSelectionStart();
  355.         int p1 = getSelectionEnd();
  356.         StyledDocument doc = getStyledDocument();
  357.         doc.setParagraphAttributes(p0, p1 - p0, attr, replace);
  358.     }
  359.  
  360.     /**
  361.      * Gets the input attributes for the pane.
  362.      *
  363.      * @return the attributes
  364.      */
  365.     public MutableAttributeSet getInputAttributes() {
  366.         return getStyledEditorKit().getInputAttributes();
  367.     }
  368.  
  369.     /**
  370.      * Gets the editor kit.
  371.      *
  372.      * @return the editor kit.
  373.      */
  374.     protected final StyledEditorKit getStyledEditorKit() {
  375.         return (StyledEditorKit) getEditorKit();
  376.     }
  377.  
  378.     /**
  379.      * @see #getUIClassID
  380.      * @see #readObject
  381.      */
  382.     private static final String uiClassID = "TextPaneUI";
  383.  
  384.  
  385.     /** 
  386.      * See readObject() and writeObject() in JComponent for more 
  387.      * information about serialization in Swing.
  388.      */
  389.     private void writeObject(ObjectOutputStream s) throws IOException {
  390.         s.defaultWriteObject();
  391.     if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  392.         ui.installUI(this);
  393.     }
  394.     }
  395.  
  396.  
  397.     // --- JEditorPane ------------------------------------
  398.  
  399.     /**
  400.      * Creates the EditorKit to use by default.  This
  401.      * is implemented to return text.StyledEditorKit.
  402.      *
  403.      * @return the editor kit
  404.      */
  405.     protected EditorKit createDefaultEditorKit() {
  406.         return new StyledEditorKit();
  407.     }
  408.  
  409.     /**
  410.      * Sets the currently installed kit for handling
  411.      * content.  This is the bound property that
  412.      * establishes the content type of the editor.
  413.      * 
  414.      * @param kit the desired editor behavior.
  415.      * @exception IllegalArgumentException if kit is not a text.StyledEditorKit
  416.      */
  417.     public final void setEditorKit(EditorKit kit) {
  418.         if (kit instanceof StyledEditorKit) {
  419.             super.setEditorKit(kit);
  420.         } else {
  421.             throw new IllegalArgumentException("Must be StyledEditorKit");
  422.         }
  423.     }
  424.  
  425.     // --- Scrollable  ----------------------------------------
  426.  
  427.     /**
  428.      * Returns true if a viewport should always force the width of this 
  429.      * Scrollable to match the width of the viewport.  
  430.      * 
  431.      * @return true if a viewport should force the Scrollables width to match its own.
  432.      */
  433.     public boolean getScrollableTracksViewportWidth() {
  434.         return true;
  435.     }
  436.  
  437.  
  438.     /**
  439.      * Returns a string representation of this JTextPane. This method 
  440.      * is intended to be used only for debugging purposes, and the 
  441.      * content and format of the returned string may vary between      
  442.      * implementations. The returned string may be empty but may not 
  443.      * be <code>null</code>.
  444.      * <P>
  445.      * Overriding paramString() to provide information about the
  446.      * specific new aspects of the JFC components.
  447.      * 
  448.      * @return  a string representation of this JTextPane.
  449.      */
  450.     protected String paramString() {
  451.         return super.paramString();
  452.     }
  453.  
  454. }
  455.